package cn.yunyichina.provider.pay.alipay.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.pay.PaymentSettingResponse;
import cn.yunyichina.provider.pay.alipay.config.Alipay;
import cn.yunyichina.provider.pay.alipay.constant.PulicEnvConstants;
import cn.yunyichina.provider.pay.alipay.dispatcher.Dispatcher;
import cn.yunyichina.provider.pay.alipay.executor.ActionExecutor;
import cn.yunyichina.utils.convert.XmlUtils;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 支付宝开发者网关
 * Created by Joe.zhou on 2017/11/27.
 */
@Service
public class AlipayGatewayServiceImpl {

    @Resource
    private Properties yaml;

    private static final Logger logger = LoggerFactory.getLogger(AlipayGatewayServiceImpl.class);


    /**
     * 支付宝发起网关入口
     * @param json
     * @interfaceName: yyt.alipay.alipay.gateway.callback.get
     * @return
     */
    public String getAlipayGatewayCallback(String json) {
        logger.info("AlipayGatewayServiceImpl.getAlipayGatewayCallback 进入回调网关地址 datas->" + json);
        String responseMsg = "";
        JSONObject jsonObject = JSONObject.parseObject(json);
        String bizContent = jsonObject.getString("biz_content");

        Map<String ,String > vmap = new HashMap<String ,String>();
        vmap.put("sign" , jsonObject.getString("sign"));
        vmap.put("sign_type" , jsonObject.getString("sign_type"));
        vmap.put("service" , jsonObject.getString("service"));
        vmap.put("charset" , jsonObject.getString("charset"));
        vmap.put("biz_content",bizContent);

        String appId = "";
        String publicKey = "";
        String privateKey = "";

        try {
            if(XmlUtils.isXml(bizContent)){
                Map<String, String> param = XmlUtils.xmlToMap(bizContent);
                appId = param.get("AppId");
                //根据appId获取公私钥
                ResCommon<PaymentSettingResponse> paymentSetting = PayService.getPayClient().queryPaymentSettingByAppId(appId);
                if(paymentSetting != null){
//                    publicKey = paymentSetting.getResult().getPublicKey();
                    publicKey = yaml.getProperty(Alipay.ALIPAY_GATEWAY_PUBLICKEY);
                    paymentSetting.getResult().setPayPublicKey(publicKey);
                    privateKey = paymentSetting.getResult().getPrivateKey();
                    //1.验签
                    verifySign(vmap, paymentSetting.getResult().getPublicKey());

                    //2. 获取业务执行器   根据请求中的 service, msgType, eventType, actionParam 确定执行器
                    ActionExecutor executor = Dispatcher.getExecutor(vmap , paymentSetting.getResult());

                    //4. 执行业务逻辑
                    responseMsg = executor.execute();

                }else{
                    logger.info("AlipayGatewayServiceImpl.getAlipayGatewayCallback 根据appId获取配置失败：" + appId);
                }
            }else{
                logger.info("bizContent is not xml:" + bizContent);
            }
        } catch (Exception e) {
            logger.error("AlipayGatewayServiceImpl.getAlipayGatewayCallback 执行验签过程异常" , e);
        } finally {
            //响应内容加签返回
            try {
                if(StringUtils.isNotBlank(publicKey) && StringUtils.isNotBlank(privateKey)){
                    responseMsg = AlipaySignature.encryptAndSign(responseMsg, publicKey, privateKey, PulicEnvConstants.CHARSET, false, true);
                }else{
                    logger.info("AlipayGatewayServiceImpl.getAlipayGatewayCallback 获取publicKey、privateKey配置为空。publicKey：" + publicKey + ",privateKey:" + privateKey);
                }
            } catch (AlipayApiException e) {
                logger.error("AlipayGatewayServiceImpl.getAlipayGatewayCallback 返回加签异常" , e);
            }
        }

        logger.info("最终返回支付宝网关结果：" + responseMsg);
        return responseMsg;
    }



    /**
     * 验签
     *
     * @param params
     * @return
     */
    private void verifySign(Map<String, String> params , String publicKey) throws AlipayApiException {
        if (!AlipaySignature.rsaCheckV2(params, publicKey, PulicEnvConstants.SIGN_CHARSET)) {
            throw new AlipayApiException("verify sign fail. 验签失败");
        }else{
            logger.info("verify sign Success. 验签成功");
        }
    }


    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        AlipayGatewayServiceImpl bean = applicationContext.getBean(AlipayGatewayServiceImpl.class);
        String str = "{\"sign\":\"Hk1CCUmfpsFho9gw4X8hbwyE6/6wBsTVcxqs0n4Qft7WQEoprYhrvjV25kkdrEVMd5QvJS9rvCU3fPHtHJhnBI38nCcPL6E7Uw1ygQvyRB44Tfaze7ZZuDZr0fb8zthDUjx4I+KbAehtObjBpUPWoOiGfzTySsrB3dCv9RIpQ9I=\",\"biz_content\":\"<?xml version=\\\"1.0\\\" encoding=\\\"gbk\\\"?><XML><AppId><![CDATA[2016080101690740]]></AppId><FromUserId></FromUserId><CreateTime><![CDATA[1512635730673]]></CreateTime><MsgType><![CDATA[event]]></MsgType><EventType><![CDATA[verifygw]]></EventType><ActionParam></ActionParam><AgreementId></AgreementId><AccountNo></AccountNo></XML>\",\"sign_type\":\"RSA\",\"service\":\"alipay.service.check\",\"charset\":\"GBK\"}";
        String alipayGatewayCallback = bean.getAlipayGatewayCallback(str);
        System.err.println(alipayGatewayCallback);
    }
}
